<script lang="ts" setup>
import { list, save, del } from "@/services/ebook";
import { onMounted, ref } from "vue";
import type { Ebook } from "@/types/ebook";
import type { FormInstance, Rule } from "ant-design-vue/es/form";
import { message, type CascaderProps } from "ant-design-vue";
import type { CategoryList } from "@/types/category";
import { all } from "@/services/category";

const columns = [
  {
    title: "封面",
    dataIndex: "cover",
  },
  {
    title: "名称",
    dataIndex: "name",
  },
  {
    title: "分类",
    key: "category",
  },
  {
    title: "文档数",
    dataIndex: "docCount",
  },
  {
    title: "阅读数",
    dataIndex: "viewCount",
  },
  {
    title: "点赞数",
    dataIndex: "voteCount",
  },
  {
    title: "操作",
    key: "action",
  },
];
const eookList = ref<Ebook[]>([]);
const pagination = ref({
  current: 1,
  pageSize: 2,
  total: 0,
});
const text = ref("");
const listLoading = ref(false);
const open = ref(false);
const formState = ref<Ebook>({});
const rules: Record<string, Rule[]> = {
  cover: [{ required: true, message: "不允许为空", trigger: "change" }],
  name: [{ required: true, message: "不允许为空", trigger: "change" }],
  category1Id: [{ required: true, message: "不允许为空", trigger: "change" }],
  category2Id: [{ required: true, message: "不允许为空", trigger: "change" }],
  description: [{ required: true, message: "不允许为空", trigger: "change" }],
};
const formRef = ref<FormInstance | null>(null);
const queryValue = ref("");
const categoryList = ref<CategoryList>([]);
const categoryListTree = ref<CategoryList>([]);
const categoryIds = ref<number[]>([]);

// 处理分页加载数据
const handleTableChange = async (page: { current: number; pageSize: number; total: number }) => {
  listLoading.value = true;
  try {
    pagination.value.current = page.current;
    const res = await list({ page: pagination.value.current, size: pagination.value.pageSize });
    eookList.value = res.content.rows;
  } finally {
    listLoading.value = false;
  }
};

// 打开编辑框，回显数据
const showEditModal = (ebook: Ebook) => {
  text.value = "编辑";
  formState.value = Object.assign({}, ebook);
  categoryIds.value = [formState.value.category1Id!, formState.value.category2Id!];
  open.value = true;
};

// 打开新增框
const showAddModal = () => {
  text.value = "新增";
  // 这三个字段后端不允许为空
  formState.value = { docCount: 0, viewCount: 0, voteCount: 0 };
  categoryIds.value = [];
  open.value = true;
};

// 处理编辑/新增提交
const handleEditOrAddOk = async () => {
  // 规则校验
  await formRef.value?.validateFields();
  // 发请求
  open.value = false;
  await save(formState.value);
  message.success("success");

  // 请求成功重新加载列表
  listLoading.value = true;
  try {
    const res = await list({ page: pagination.value.current, size: pagination.value.pageSize });
    eookList.value = res.content.rows;
    pagination.value.total = res.content.total;
  } finally {
    listLoading.value = false;
  }
};

// 处理编辑/新增取消
const handleEditOrAddCancel = () => {
  open.value = false;
  // 对整个表单进行重置，将所有字段值重置为初始值并移除校验结果
  formRef.value?.resetFields();
};

// 删除
const handleDel = async (id: number) => {
  await del(id);
  message.success("success");
  // 请求成功重新加载列表
  listLoading.value = true;
  // 处理分页删除最后一条数据页码的问题
  if (eookList.value.length === 1 && pagination.value.current > 1) {
    pagination.value.current--;
  }
  try {
    const res = await list({ page: pagination.value.current, size: pagination.value.pageSize });
    eookList.value = res.content.rows;
    pagination.value.total = res.content.total;
  } finally {
    listLoading.value = false;
  }
};

// 查询
const query = async () => {
  pagination.value.current = 1;
  listLoading.value = true;
  try {
    const res = await list({
      page: pagination.value.current,
      size: pagination.value.pageSize,
      name: queryValue.value,
    });
    eookList.value = res.content.rows;
    pagination.value.total = res.content.total;
  } finally {
    listLoading.value = false;
  }
};

// 处理级联选择选择完成后的回调
const onChange: CascaderProps["onChange"] = (value) => {
  formState.value.category1Id = Number(value[0]);
  formState.value.category2Id = Number(value[1]);
};

// 扁平化数组转树形结构
const attr2Tree = (arr: CategoryList, parent: number) => {
  const data: CategoryList = [];
  arr.forEach((item) => {
    if (item.parent === parent) {
      item.children = attr2Tree(arr, item.id!);
      data.push(item);
    }
  });
  return data;
};

// 根据id获取分类名称
const getCategoryName = (id: number) => categoryList.value.filter((item) => item.id === id)[0].name;

onMounted(async () => {
  listLoading.value = true;
  try {
    // 加载ebook列表
    const res1 = await list({ page: pagination.value.current, size: pagination.value.pageSize });
    // 加载分类列表
    const res2 = await all();

    eookList.value = res1.content.rows;
    pagination.value.total = res1.content.total;
    categoryList.value = res2.content;
    categoryListTree.value = attr2Tree(res2.content, 0);
  } finally {
    listLoading.value = false;
  }
});
</script>
<template>
  <a-layout>
    <a-layout-content
      :style="{ background: '#fff', padding: '24px', margin: 0, minHeight: '280px' }"
    >
      <a-space style="margin-bottom: 20px">
        <a-input v-model:value="queryValue" placeholder="请输入查询关键字" />
        <a-button type="primary" @click="query">查询</a-button>
        <a-button type="primary" @click="showAddModal">新增</a-button>
      </a-space>

      <a-table
        :columns="columns"
        :data-source="eookList"
        rowKey="id"
        :pagination
        :loading="listLoading"
        @change="handleTableChange"
      >
        <template #bodyCell="{ column, record }">
          <template v-if="column.dataIndex === 'cover'">
            <a-avatar shape="square" size="large" :src="record.cover"> </a-avatar>
          </template>
          <template v-if="column.key === 'category'">
            <span>
              {{ getCategoryName(record.category1Id) }}
              /
              {{ getCategoryName(record.category2Id) }}
            </span>
          </template>
          <template v-if="column.key === 'action'">
            <a-space>
              <router-link :to="`/admin/doc?ebookId=${record.id}`">
                <a-button type="primary">文档管理</a-button>
              </router-link>

              <a-button type="primary" @click="showEditModal(record)">编辑</a-button>
              <a-button type="primary" danger
                ><a-popconfirm
                  title="Are you sure delete this task?"
                  ok-text="Yes"
                  cancel-text="No"
                  @confirm="handleDel(record.id)"
                >
                  <a href="#">删除</a>
                </a-popconfirm></a-button
              >
            </a-space>
          </template>
        </template>
      </a-table>

      <a-modal v-model:open="open" :title="text" @cancel="handleEditOrAddCancel">
        <a-form
          ref="formRef"
          v-if="formState"
          :model="formState"
          :rules="rules"
          name="basic"
          :label-col="{ span: 4 }"
          :wrapper-col="{ span: 20 }"
          autocomplete="off"
        >
          <a-form-item label="封面" name="cover">
            <a-input v-model:value="formState.cover" />
          </a-form-item>
          <a-form-item label="名称" name="name">
            <a-input v-model:value="formState.name" />
          </a-form-item>
          <a-form-item label="分类" name="category">
            <a-cascader
              v-model:value="categoryIds"
              :field-names="{ label: 'name', value: 'id' }"
              :options="categoryListTree"
              placeholder="请选择分类"
              @change="onChange"
            />
          </a-form-item>
          <a-form-item label="描述" name="description">
            <a-input v-model:value="formState.description" />
          </a-form-item>
        </a-form>
        <template #footer>
          <a-button @click="handleEditOrAddCancel">取消</a-button>
          <a-button type="primary" @click="handleEditOrAddOk"> 提交 </a-button>
        </template>
      </a-modal>
    </a-layout-content>
  </a-layout>
</template>
<style scoped></style>
